// --------------------------------------------------------------------------------------------------------------------
// <copyright file="UILayerList.cs" company="Open Trader">
//   Copyright (c) David Denis (david.denis@systemathics.com)
// </copyright>
// <summary>
//   |  Open Trader - The Open Source Systematic Trading Platform
//   |
//   |  This program is free software: you can redistribute it and/or modify
//   |  it under the terms of the GNU General Public License as published by
//   |  the Free Software Foundation, either version 2 of the License, or
//   |  (at your option) any later version.
//   |
//   |  This program is distributed in the hope that it will be useful,
//   |  but WITHOUT ANY WARRANTY; without even the implied warranty of
//   |  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   |  GNU General Public License for more details.
//   |
//   |  You should have received a copy of the GNU General Public License
//   |  along with this program.  If not, see http://www.gnu.org/licenses
//   |
//   |  Up to date informations about Open Trader can be found at :
//   |    http://opentrader.org
//   |    http://opentrader.codeplex.com
//   |
//   |  For professional services, please visit us at :
//   |    http://www.systemathics.com
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Org.OpenTrader.Framework.Forge.UI.Forms
{
    #region Using Directives

    using System.Drawing;
    using System.Runtime.Remoting;
    using System.Windows.Forms;

    using Org.OpenTrader.Framework.Enums;
    using Org.OpenTrader.Framework.Events;
    using Org.OpenTrader.Framework.Forge.Events;
    using Org.OpenTrader.Framework.Forge.Interfaces;
    using Org.OpenTrader.Framework.LiveObjects.Interfaces;
    using Org.OpenTrader.Framework.UI.Forms;

    #endregion

    /// <summary>
    /// The ui layer list.
    /// </summary>
    public partial class UILayerList : UIControl
    {
        // private IDictionary<Guid,EConnectionStatus> statuses = new Map

        // Related service (using layers)
        #region Constants and Fields

        /// <summary>
        /// The service.
        /// </summary>
        private IService service;

        #endregion

        #region Constructors and Destructors

        /// <summary>
        /// Initializes a new instance of the <see cref="UILayerList"/> class.
        /// </summary>
        public UILayerList()
        {
            this.InitializeComponent();
        }

        #endregion

        #region Delegates

        /// <summary>
        /// The task delegate.
        /// </summary>
        public delegate void TaskDelegate();

        /// <summary>
        /// The connect disconnect delegate.
        /// </summary>
        private delegate Status ConnectDisconnectDelegate();

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets Service.
        /// </summary>
        public IService Service
        {
            get
            {
                return this.service;
            }

            set
            {
                this.service = value;

                if (this.service == null)
                {
                    return;
                }

                foreach (var plugin in this.service.Plugins)
                {
                    var layer = plugin as ILayer;
                    try
                    {
                        layer.ConnectionEventCB += this.OnConnectionEvent;
                    }
                    catch
                    {
                    }
                }
            }
        }

        #endregion

        #region Methods

        /// <summary>
        /// The handler_ Connection event.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="args">
        /// The args.
        /// </param>
        private void OnConnectionEvent(object sender, ConnectionEventArgs args)
        {
            this.BeginInvoke(new TaskDelegate(() => this.uiVirtualGrid1.Refresh()), null);
        }

        /// <summary>
        /// The ui virtual grid 1_ cell click.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void OnVirtualGrid1CellClick(object sender, DataGridViewCellEventArgs e)
        {
            try
            {
                // connect/disconnect buttons
                if (e.ColumnIndex == 3)
                {
                    if (this.Service == null)
                    {
                        return;
                    }

                    if (e.RowIndex >= this.Service.Plugins.Length || e.RowIndex < 0)
                    {
                        return;
                    }

                    // A live object always have a descriptor
                    var liveObject = this.Service.Plugins[e.RowIndex] as ILiveObject;

                    // A plugin is always local, descriptor can only be local
                    var liveObjectDescriptorLocal = liveObject.Descriptor as ILocalLiveObjectDescriptor;

                    // As a layer
                    var layer = this.Service.Plugins[e.RowIndex] as ILayer;

                    var status = layer.ConnectionStatus;
                    if (status == EConnectionStatus.Disconnected)
                    {
                        var v = new ConnectDisconnectDelegate(layer.Connect);
                        v.BeginInvoke(null, null);
                    }
                    else if (status == EConnectionStatus.Connected)
                    {
                        var v = new ConnectDisconnectDelegate(layer.Disconnect);
                        v.BeginInvoke(null, null);
                    }
                }
            }
            catch (RemotingException)
            {
            }
        }

        /// <summary>
        /// The ui virtual grid 1_ ui grid query cell info.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void OnVirtualGrid1UIGridQueryCellInfo(object sender, VirtualGridEventArgs.QueryCellInfo e)
        {
            if (this.Service == null)
            {
                return;
            }

            if (e.RowIndex >= this.Service.Plugins.Length)
            {
                return;
            }

            try
            {
                // A live object always have a descriptor
                var plugin = this.Service.Plugins[e.RowIndex] as ILiveObject;

                // A plugin is always local, descriptor can only be local
                var liveObjectDescriptorLocal = plugin.Descriptor as ILocalLiveObjectDescriptor;

                // As a layer
                var layer = plugin as ILayer;
                if (layer == null)
                {
                    return;
                }

                EConnectionStatus status;

                switch (e.ColumnIndex)
                {
                    case 0:
                        e.Value = string.Format("{0} ({1})", liveObjectDescriptorLocal.Name, liveObjectDescriptorLocal.Label);
                        e.ToolTip = liveObjectDescriptorLocal.ClassType + " : " + liveObjectDescriptorLocal.InterfaceType;
                        break;

                    case 1:
                        e.Value = layer.ConnectionURL;
                        break;

                    case 2:
                        status = layer.ConnectionStatus;
                        if (status == EConnectionStatus.Connecting)
                        {
                            this.uiVirtualGrid1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.Yellow;
                        }
                        else if (status == EConnectionStatus.Connected)
                        {
                            this.uiVirtualGrid1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.LightGreen;
                        }
                        else if (status == EConnectionStatus.Disconnected)
                        {
                            this.uiVirtualGrid1[e.ColumnIndex, e.RowIndex].Style.BackColor = Color.Orange;
                        }

                        e.Value = status;
                        break;

                    case 3:
                        status = layer.ConnectionStatus;
                        if (status == EConnectionStatus.Connected)
                        {
                            e.Value = "Disconnect";
                        }
                        else if (status == EConnectionStatus.Disconnected)
                        {
                            e.Value = "Connect";
                        }
                        else
                        {
                            e.Value = "Wait ...";
                        }

                        break;
                }
            }
            catch (RemotingException)
            {
                e.Value = "Remoting Exception";
            }
        }

        /// <summary>
        /// The ui virtual grid 1_ ui grid query row count.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The e.
        /// </param>
        private void OnVirtualGrid1UIGridQueryRowCount(object sender, VirtualGridEventArgs.QueryRowCount e)
        {
            if (this.Service != null)
            {
                e.RowCount = this.Service.Plugins.Length;
            }
        }

        #endregion
    }
}